001    package EVolve;
002    
003    /* EVolve - an Extensible Software Visualization Framework
004     * Copyright (C) 2001-2002 Qin Wang
005     *
006     * This library is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Library General Public
008     * License as published by the Free Software Foundation; either
009     * version 2 of the License, or (at your option) any later version.
010     *
011     * This library is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Library General Public License for more details.
015     *
016     * You should have received a copy of the GNU Library General Public
017     * License along with this library; if not, write to the
018     * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
019     * Boston, MA 02111-1307, USA.
020     */
021    
022    /*
023     * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/
024     */
025    
026    import EVolve.*;
027    import EVolve.exceptions.DataProcessingException;
028    import EVolve.exceptions.CancelLoadDataException;
029    import EVolve.exceptions.EVolveException;
030    import EVolve.data.NumericStringComparator;
031    import EVolve.data.*;
032    import java.io.*;
033    import java.util.*;
034    import javax.swing.*;
035    
036    public class DemoSource implements DataSource {
037        private final String dsourceName = "DemoSource";
038        private String fn = null; // data file name
039    
040        private RandomAccessFile file;
041    
042        private EntityBuilder classBuilder;
043    
044        private EntityBuilder threadBuilder;
045    
046        private EntityBuilder methodBuilder;
047        private FieldDefinition methodDefiningClass;
048    
049        private EntityBuilder locationBuilder;
050    
051        private EntityBuilder sizeBuilder;
052    
053        private EventBuilder allocationBuilder;
054        private FieldDefinition allocationObjectCount;
055        private FieldDefinition allocationObjectSize;
056        private FieldDefinition allocationBytecode;
057        private FieldDefinition allocationObjectType;
058        private FieldDefinition allocationThread;
059        private FieldDefinition allocationMethod;
060        private FieldDefinition allocationLocation;
061        private FieldDefinition allocationSize;
062        private FieldDefinition allocationFieldSum;
063        private FieldDefinition allocationFieldCounter;
064    
065        private EventBuilder invocationBuilder;
066        private FieldDefinition invocationNumber;
067        private FieldDefinition invocationBytecode;
068        private FieldDefinition invocationThread;
069        private FieldDefinition invocationMethod;
070        private FieldDefinition invocationLocation;
071        private FieldDefinition invocationFieldCounter;
072    
073    
074        private ElementDefinition[] definition;
075        private int definitionCounter;
076    
077        private TreeMap classMap;
078        private TreeMap threadMap;
079        private TreeMap methodMap;
080        private TreeMap locationMap;
081        private TreeMap sizeMap;
082    
083        private long counter[];
084    
085        public void init() throws EVolveException {
086            String lastName = fn;
087    
088            fn = Scene.getDataFileName();
089            if (fn == null) {
090                JFileChooser fc = new JFileChooser(Scene.getUIManager().getLastDataDir());
091                if (fc.showOpenDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) {
092                    try {
093                        file = new RandomAccessFile(fc.getSelectedFile(), "r");
094                        fn = fc.getSelectedFile().getName();
095                        Scene.setDataFilename(fc.getSelectedFile().getPath());
096                        Scene.getUIManager().setLastDataDir(fc.getSelectedFile().getPath());
097                        Scene.setDataFilename(null);
098                    } catch (IOException e) {
099                        throw new DataProcessingException("IO exception occurred when access data file.");
100                    }
101                } else {
102                    fn = lastName;
103                    throw new CancelLoadDataException();
104                }
105            } else {
106                try {
107                    file = new RandomAccessFile(fn, "r");
108                } catch (IOException e) {
109                    throw new DataProcessingException("File loading failed.");
110                }
111            }
112    
113        }
114    
115        public void startBuildDefinition() throws DataProcessingException {
116            String[] propertySum = {"time","sum"};
117            String[] propertyCount = {"time","count"};
118            String[] propertyAmount = {"amount"};
119            String[] propertyCoordinate = {"time","coordinate"};
120            String[] propertyIndicator = {"indicator"};
121            String[] propertyThread = {"reference","thread"};
122    
123            definition = new ElementDefinition[7];
124    
125            classBuilder = new EntityBuilder("Class", "Class");
126            definition[0] = classBuilder.buildDefinition();
127    
128            threadBuilder = new EntityBuilder("Thread", "Thread");
129            definition[1] = threadBuilder.buildDefinition();
130    
131            methodBuilder = new EntityBuilder("Method", "Method");
132            methodDefiningClass = methodBuilder.buildReferenceDefinition("Defining Class", classBuilder, null, "Defining class of the method");
133            definition[2] = methodBuilder.buildDefinition();
134    
135            locationBuilder = new EntityBuilder("Location", "Location in Method");
136            definition[3] = locationBuilder.buildDefinition();
137    
138            sizeBuilder = new EntityBuilder("Size", "Object Size");
139            sizeBuilder.addComparator(new NumericStringComparator());
140            definition[4] = sizeBuilder.buildDefinition();
141    
142            allocationBuilder = new EventBuilder("Object Allocation", "Object allocation event");
143            allocationFieldSum = allocationBuilder.buildValueDefinition("Memory Allocated", propertySum, "Size of memory allocated");
144            allocationFieldCounter = allocationBuilder.buildValueDefinition("Allocations", propertyCount, "Number of objects allocated");
145            allocationObjectCount = allocationBuilder.buildValueDefinition("Object Count", propertyAmount, "Number of objects allocated");
146            allocationObjectSize = allocationBuilder.buildValueDefinition("Memory Allocated", propertyAmount, "Size of memory allocated");
147            allocationBytecode = allocationBuilder.buildValueDefinition("Bytecode", propertyCoordinate, "Bytecode sequence");
148            allocationObjectType = allocationBuilder.buildReferenceDefinition("Object Type", classBuilder, null, "Type of the object");
149            allocationThread = allocationBuilder.buildReferenceDefinition("Thread", threadBuilder, propertyThread, "Thread in which the object is allocated");
150            allocationMethod = allocationBuilder.buildReferenceDefinition("Allocating Methods", methodBuilder, null, "Method that creates the object");
151            allocationLocation = allocationBuilder.buildReferenceDefinition("Allocating Locations", locationBuilder, null, "Location where the object is created");
152            allocationSize = allocationBuilder.buildReferenceDefinition("Allocation Size", sizeBuilder, null, "Allocation Size");
153            definition[5] = allocationBuilder.buildDefinition();
154    
155            invocationBuilder = new EventBuilder("Method Invocation", "Method invocation event");
156            invocationFieldCounter = invocationBuilder.buildValueDefinition("Invocations", propertyCount, "Total number of invocations");
157            invocationNumber = invocationBuilder.buildValueDefinition("Number of Invocations", propertyAmount, "Total number of invocations");
158            invocationBytecode = invocationBuilder.buildValueDefinition("Bytecode", propertyCoordinate, "Bytecode sequence");
159            invocationThread = invocationBuilder.buildReferenceDefinition("Thread", threadBuilder, propertyThread, "Thread in which the method is invoked");
160            invocationMethod = invocationBuilder.buildReferenceDefinition("Method", methodBuilder, null, "Method that is invoked");
161            invocationLocation = invocationBuilder.buildReferenceDefinition("Invoking Locations", locationBuilder, null, "Location where the method is invoked");
162            definition[6] = invocationBuilder.buildDefinition();
163    
164            definitionCounter = -1;
165            counter = new long[definition.length];
166            for (int i=0; i<counter.length; i++)
167                counter[i] = 0;
168        }
169    
170        public ElementDefinition getNextDefinition() throws DataProcessingException {
171            definitionCounter++;
172            if (definitionCounter < definition.length) {
173                return definition[definitionCounter];
174            } else {
175                return null;
176            }
177        }
178    
179        private String getSub(String line, int part) {
180            int start = line.indexOf(' ') + 1;
181            int i = 1;
182            while (i < part) {
183                start = line.indexOf(' ', start) + 1;
184                i++;
185            }
186            int end = line.indexOf(' ', start);
187            if (end == -1) {
188                return line.substring(start);
189            } else {
190                return line.substring(start, end);
191            }
192        }
193    
194        public void startBuildEntity() throws DataProcessingException {
195            try {
196                file.seek(0);
197    
198                classMap = new TreeMap();
199                threadMap = new TreeMap();
200                methodMap = new TreeMap();
201                locationMap = new TreeMap();
202                sizeMap = new TreeMap();
203            } catch (IOException e) {
204                throw new DataProcessingException("File processing failed.");
205            }
206        }
207    
208        public Entity getNextEntity() throws DataProcessingException {
209            try {
210                Entity returnVal = null;
211                String line = file.readLine();
212    
213                while ((returnVal == null) && (line != null) && (line.length()>0)) {
214                    line = line.trim();
215                    char ch = line.charAt(0);
216    
217                    if (ch == 'C') {
218                        classBuilder.newEntity(getSub(line, 1));
219                        returnVal = classBuilder.buildEntity();
220                        classMap.put(getSub(line, 2), returnVal);
221                    } else if (ch == 'T') {
222                        threadBuilder.newEntity(getSub(line, 1));
223                        returnVal = threadBuilder.buildEntity();
224                        threadMap.put(getSub(line, 2), returnVal);
225                    } else if (ch == 'M') {
226                        methodBuilder.newEntity(getSub(line, 1));
227                        methodBuilder.addReferenceField(methodDefiningClass, (Entity)(classMap.get(getSub(line, 3))));
228                        returnVal = methodBuilder.buildEntity();
229                        methodMap.put(getSub(line, 2), returnVal);
230                    } else if (ch == 'L') {
231                        locationBuilder.newEntity(getSub(line, 1));
232                        returnVal = locationBuilder.buildEntity();
233                        locationMap.put(getSub(line, 2), returnVal);
234                    } else if (ch == 'O') {
235                        String size = getSub(line, 6);
236                        if (!sizeMap.containsKey(size)) {
237                            sizeBuilder.newEntity(size);
238                            returnVal = sizeBuilder.buildEntity();
239                            sizeMap.put(size, returnVal);
240                        }
241                        counter[5]++;
242                    } else if (ch == '+') {
243                        counter[6]+=2;
244                    }
245    
246                    if (returnVal == null) {
247                        line = file.readLine();
248                    }
249                }
250    
251                return returnVal;
252            } catch (IOException e) {
253                throw new DataProcessingException("File processing failed.");
254            }
255        }
256    
257        public void startBuildEvent() throws DataProcessingException {
258            try {
259                file.seek(0);
260            } catch (IOException e) {
261                throw new DataProcessingException("File processing failed.");
262            }
263        }
264    
265        public Event getNextEvent() throws DataProcessingException {
266            try {
267                Event returnVal = null;
268                String line = file.readLine();
269    
270                while ((returnVal == null) && (line != null)) {
271                    line = line.trim();
272                    char ch = line.charAt(0);
273    
274                    if (ch == 'O') {
275                        allocationBuilder.newEvent();
276                        String size = getSub(line, 6);
277                        allocationBuilder.addValueField(allocationObjectCount, 1);
278                        allocationBuilder.addValueField(allocationObjectSize, Integer.parseInt(getSub(line, 6)));
279                        allocationBuilder.addValueField(allocationFieldCounter, 1);
280                        allocationBuilder.addValueField(allocationFieldSum, Integer.parseInt(getSub(line, 6)));
281                        allocationBuilder.addValueField(allocationBytecode, Integer.parseInt(getSub(line, 1)));
282                        allocationBuilder.addReferenceField(allocationObjectType, (Entity)(classMap.get(getSub(line, 5))));
283                        allocationBuilder.addReferenceField(allocationThread, (Entity)(threadMap.get(getSub(line, 2))));
284                        allocationBuilder.addReferenceField(allocationMethod, (Entity)(methodMap.get(getSub(line, 3))));
285                        allocationBuilder.addReferenceField(allocationLocation, (Entity)(locationMap.get(getSub(line, 4))));
286                        allocationBuilder.addReferenceField(allocationSize, (Entity)(sizeMap.get(size)));
287                        returnVal = allocationBuilder.buildEvent();
288                    } else if (ch == '+') {
289                        invocationBuilder.newEvent();
290                        invocationBuilder.addValueField(invocationNumber, 1);
291                        invocationBuilder.addValueField(invocationFieldCounter, 1);
292                        invocationBuilder.addValueField(invocationBytecode, Integer.parseInt(getSub(line, 1)));
293                        invocationBuilder.addReferenceField(invocationThread, (Entity)(threadMap.get(getSub(line, 2))));
294                        invocationBuilder.addReferenceField(invocationMethod, (Entity)(methodMap.get(getSub(line, 3))));
295                        invocationBuilder.addReferenceField(invocationLocation, (Entity)(locationMap.get(getSub(line, 4))));
296                        returnVal = invocationBuilder.buildEvent();
297                    } else if (ch == '-') {
298                        invocationBuilder.newEvent(true);
299                        invocationBuilder.addValueField(invocationNumber, 1);
300                        invocationBuilder.addValueField(invocationBytecode, Integer.parseInt(getSub(line, 1)));
301                        invocationBuilder.addReferenceField(invocationThread, (Entity)(threadMap.get(getSub(line, 2))));
302                        invocationBuilder.addReferenceField(invocationMethod, (Entity)(methodMap.get(getSub(line, 3))));
303                        invocationBuilder.addReferenceField(invocationLocation, (Entity)(locationMap.get(getSub(line, 4))));
304                        returnVal = invocationBuilder.buildEvent();
305                    }
306    
307                    if (returnVal == null) {
308                        line = file.readLine();
309                    }
310                }
311    
312                return returnVal;
313            } catch (IOException e) {
314                throw new DataProcessingException("File processing failed.");
315            }
316        }
317    
318        public String getName() {
319            return dsourceName;
320        }
321    
322        public String getFileName() {
323            return fn;
324        }
325    
326        public long getTotalNumberOfEvents() {
327            long total = 0;
328    
329            for (int i=0; i<definition.length; i++)
330                total = total + counter[i];
331    
332            return total;
333        }
334    
335        public long getNumberOfEvents(String definitionName) {
336            long number = 0;
337    
338            for (int i=0; i<definition.length; i++) {
339                if (definition[i].getName().equals(definitionName)) {
340                    number = counter[i];
341                    if (definitionName.equals("Method Invocation")) number = number/2;
342                    break;
343                }
344            }
345    
346            return number;
347        }
348    }